#include <qwt_plot.h>
#include <qwt_painter.h>
#include <qwt_scale_map.h>
#include <qstring.h>
#include <qpainter.h>
#include "peakitem.h"
//
class PeakItem::PrivateData
{
public:
	int attributes;
	CPointerPeakData data;
	QColor color;
};

PeakItem::PeakItem(const QwtText &title):
	QwtPlotItem(title)
{
	init();
}

PeakItem::PeakItem(const QString &title):
	QwtPlotItem(QwtText(title))
{
	init();
}

PeakItem::~PeakItem()
{
	delete d_data;
}

void PeakItem::init()
{
	d_data = new PrivateData();
	d_data->attributes = PeakItem::Auto;

	setItemAttribute(QwtPlotItem::AutoScale, true);
	setItemAttribute(QwtPlotItem::Legend, true);

	setZ(20.0);
}

void PeakItem::setData(const CPointerPeakData & data)
{
	if( &d_data->data != &data ) {
		d_data->data = data;
		itemChanged();
	}
}

const CPointerPeakData & PeakItem::data() const
{
	return d_data->data;
}

void PeakItem::setColor(const QColor &color)
{
	if ( d_data->color != color )
	{
		d_data->color = color;
		itemChanged();
	}
}

QColor PeakItem::color() const
{
	return d_data->color;
}

QwtDoubleRect PeakItem::boundingRect() const
{
	return d_data->data.boundingRect();
}


int PeakItem::rtti() const
{
	return QwtPlotItem::Rtti_PlotUserItem;
}

void PeakItem::setPeakItemAttribute(PeakItemAttribute attribute, bool on)
{
	if ( bool(d_data->attributes & attribute) == on )
		return;

	if ( on )
		d_data->attributes |= attribute;
	else
		d_data->attributes &= ~attribute;

	itemChanged();
}

bool PeakItem::testPeakItemAttribute(PeakItemAttribute attribute) const
{
	return d_data->attributes & attribute;
}

void PeakItem::draw(QPainter *painter, const QwtScaleMap &xMap, 
	const QwtScaleMap &yMap, const QRect &rect) const
{
	const CPointerPeakData &iData = d_data->data;

	painter->setPen(QPen(d_data->color));

	int size = iData.size();
	if( size <= 0 )
		return;

	int left = rect.left();
	int right = rect.right();
	// szukanie pierwszego x znajdujacego sie w widocznym przedziale
	int x;
	int i;
	for( i = 0; i < size; i++ ) {
		x = xMap.transform( iData.value(i) );
		if( x > left && x < right )
			break; // znaleziony :)
	}
	// wyjdz jesli nie znaleziono zadnej widocznej linii
	if( i == size )
		return;

	int y_max = yMap.transform( iData.interval(i).minValue() ); // (odwrocona os y)
	int y_min = yMap.transform( iData.interval(i).maxValue() ); 

	// jesli tylko jedna linia, to narysuj i wyjdz
	if( i == size - 1 ) {
		QwtPainter::drawLine( painter, x, y_min, x, y_max );
		return; 
	}

	int xo, yo_min, yo_max;
	bool buffered = false;

	// sprawdz i przefiltruj reszte
	for ( i = i + 1; i < size; i++ )
	{
		int xi = xMap.transform( iData.value(i) );
		if( xi < rect.left() || xi > rect.right() )
			continue;

		int yi_max = yMap.transform( iData.interval(i).minValue() ); 
		int yi_min = yMap.transform( iData.interval(i).maxValue() ); 
		
		if( xi == x ) {
			// poszerzenie linii
			if( yi_min < y_min ) y_min = yi_min;
			if( yi_max > y_max ) y_max = yi_max;
		} else {
			if( buffered ) {
				if( y_min - yo_max > 1 )
					QwtPainter::drawLine( painter, xo, yo_max, x, y_min );
				else if( yo_min - y_max > 1 )
					QwtPainter::drawLine( painter, xo, yo_min, x, y_max );
			} else
				buffered = true;
			QwtPainter::drawLine( painter, x, y_min, x, y_max );
			// zapamietaj co zostalo narysowane
			xo = x;
			yo_min = y_min;
			yo_max = y_max;
			// oraz nowa linie
			x = xi;
			y_min = yi_min;
			y_max = yi_max;
		}
	}
	// narysuj pamietane linie
	if( buffered ) {
		if( y_min - yo_max > 1 )
			QwtPainter::drawLine( painter, xo, yo_max, x, y_min );
		else if( yo_min - y_max > 1 )
			QwtPainter::drawLine( painter, xo, yo_min, x, y_max );
	}
	QwtPainter::drawLine( painter, x, y_min, x, y_max );
}
//
